package com.txsj.scan.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

import com.greendao.EpcInfoDao;
import com.greendao.RecordInfoDao;
import com.txsj.scan.Constants;
import com.txsj.scan.bean.BaseListResult;
import com.txsj.scan.bean.EpcInfo;
import com.txsj.scan.bean.RecordInfo;
import com.txsj.scan.db.GreenDaoUtils;
import com.txsj.scan.http.ApiServer;
import com.txsj.scan.http.requestframework.RetrofitManager;
import com.txsj.scan.utils.AppDateMgr;
import com.txsj.scan.utils.MD5Util;
import com.txsj.scan.utils.PreferenceUtil;
import com.txsj.scan.utils.Trace;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

public class UpdateService extends Service {

    private long lastTime = 0;
    // 设置变量
    // 可重试次数
    private int maxConnectCount = 20;
    // 当前已重试次数
    private int currentRetryGoodsCount = 0;//商品的
    private int currentRetryLabelCount = 0;//标签的
    // 重试等待时间
    private int waitRetryGoodsTime = 0;
    private int waitRetryLabelTime = 0;
    // 当前分页数量
    private int goodsPageIndex = 1;
    private int tagPageIndex = 1;

    private Timer mTimer;
    private TimerTask timerTask;

    private long times_long = 1000 * 60 * 60 * 2;
//    private long times_long = 1000 * 20;

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        List<RecordInfo> list = GreenDaoUtils.getSingleTon().getmDaoSession().getRecordInfoDao().queryBuilder()
                .where(RecordInfoDao.Properties.Type.eq(Constants.EPC_GOODS_INFO))
                .list();
        if (null != list && list.size() > 0) {
            Trace.e("UpDateService:wcj=========" + AppDateMgr.formatDateTime(list.get(0).getUpdate_time()));
        }

        if (null == mTimer) {
            mTimer = new Timer();
        }
        mTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                long currentTime = System.currentTimeMillis();
                if (System.currentTimeMillis() - lastTime > times_long) {
                    lastTime = currentTime;
                    getGoodsAndLabelHttp();
                }
            }
        }, times_long, times_long);
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 请求商品和标签数据
     */
    private void getGoodsAndLabelHttp() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                getEpcRetrofitHttp();
//                getGoodsLabel();
            }
        }).start();
    }

    /**
     * 获取标签数据
     * 韩断线重连机制
     */
    public void getEpcRetrofitHttp() {
        Map<String, String> params = new HashMap<>();
        StringBuilder builder = new StringBuilder();
        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID, ""));
        builder.append("|");
        builder.append(PreferenceUtil.getInstance().getInt(PreferenceUtil.USER_ID, 0));
        builder.append("|");
        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.TOKEN, ""));
        builder.append("|");
        builder.append(0);
        builder.append("|");
        params.put("brandtoken", builder.toString());
        params.put("select_brand", PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID, ""));
        params.put("brandid", PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID, ""));
        params.put("page_index", tagPageIndex + "");
        params.put("page_size", "10000");
        params.put("timeStamp", System.currentTimeMillis() / 1000 + "");//加时间戳参数
        params.put("sign", MD5Util.md5(params));//md5加密并加参数

        RetrofitManager.getDefault().create(ApiServer.class).getEpcListUrl(RetrofitManager.getHeader(), params)
                .retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
                    @Override
                    public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
                        return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
                            @Override
                            public ObservableSource<?> apply(Throwable throwable) throws Exception {
                                // 输出异常信息
                                Trace.e("UpdateService，wcj,Tag+++++：" + throwable.toString());
                                /**
                                 * 需求1：根据异常类型选择是否重试
                                 * 即，当发生的异常 = 网络异常 = IO异常 才选择重试
                                 */
//                                if (throwable instanceof IOException) {
//                                    Trace.e("UpdateService，wcj+++++：" + "属于IO异常，需重试");
                                /**
                                 * 需求2：限制重试次数
                                 * 即，当已重试次数 < 设置的重试次数，才选择重试
                                 */
                                if (currentRetryLabelCount < maxConnectCount) {
                                    // 记录重试次数
                                    currentRetryLabelCount++;
                                    Trace.e("UpdateService，wcj,Tag+++++：重复次数" + +currentRetryLabelCount);
                                    /**
                                     *  需求2：实现重试
                                     *  通过返回的Observable发送的事件 = Next事件，从而使得retryWhen（）重订阅，最终实现重试功能
                                     *  * *
                                     *  需求3：延迟1段时间再重试
                                     *  * 采用delay操作符 = 延迟一段时间发送，以实现重试间隔设置
                                     *  *
                                     *  * 需求4：遇到的异常越多，时间越长 *
                                     *  在delay操作符的等待时间内设置 = 每重试1次，增多延迟重试时间1s *
                                     */
                                    // 设置等待时间
                                    waitRetryLabelTime = 1000 + waitRetryLabelTime * 1000;
                                    Trace.e("UpdateService，wcj,Tag+++++： 等待时间 =" + waitRetryLabelTime);
                                    return Observable.just(1).delay(waitRetryLabelTime, TimeUnit.MILLISECONDS);
                                } else {
                                    // 若重试次数已 > 设置重试次数，则不重试
                                    // 通过发送error来停止重试（可在观察者的onError（）中获取信息）
                                    return Observable.error(new Throwable("重试次数已超过设置次数 = " + currentRetryLabelCount + "，即 不再重试"));
                                }
//                                }
                                // 若发生的异常不属于I/O异常，则不重试
                                // 通过返回的Observable发送的事件 = Error事件 实现（可在观察者的onError（）中获取信息）
//                                else {
//                                    return Observable.error(new Throwable("发生了非网络异常（非I/O异常）"));
//                                }
                            }
                        });
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<BaseListResult<EpcInfo>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(BaseListResult<EpcInfo> baseBean) {
//                        Trace.e("商品数据： " + baseBean.getData());
                        if (baseBean.isSuccess()) {
                            List<EpcInfo> list = baseBean.getData();
                            if (null != list && list.size() > 0) {
                                EpcInfoDao epcInfoDao = GreenDaoUtils.getSingleTon().getmDaoSession().getEpcInfoDao();
                                for (EpcInfo info : list) {
                                    epcInfoDao.insertOrReplace(info);
                                }
                                PreferenceUtil.getInstance().commitBoolean(PreferenceUtil.GOODS_IS_LOADED, true);//本地记录加载成功
                                if (list.size() == 10000) {
                                    tagPageIndex++;
                                    getEpcRetrofitHttp();
                                    Trace.e("UpdateService,wcj,Tag+++++++++++++++" + tagPageIndex);
                                }
                            } else {
                                Trace.e("UpdateService，wcj,Tag+++++：" + "数据为空");
                            }
                        } else {
                            Trace.e("UpdateService，wcj,Tag+++++：" + baseBean.getType());
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Trace.e("UpdateService，wcj+++++：" + e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }


    /**
     * 获取品牌下所有的商品数据
     * 含有断线重连机制，一直重连
     */
//    public void getGoodsLabel() {
//        Map<String, String> params = new HashMap<>();
//        StringBuilder builder = new StringBuilder();
//        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID,""));
//        builder.append("|");
//        builder.append(PreferenceUtil.getInstance().getInt(PreferenceUtil.USER_ID,0));
//        builder.append("|");
//        builder.append(PreferenceUtil.getInstance().getString(PreferenceUtil.TOKEN,""));
//        builder.append("|");
//        builder.append(0);
//        builder.append("|");
//        params.put("brandtoken", builder.toString());
//        params.put("select_brand", PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID,""));
//        params.put("brandid", PreferenceUtil.getInstance().getString(PreferenceUtil.BRAND_ID,""));
//        params.put("page_index", goodsPageIndex+"");
//        params.put("page_size", "10000");
//        params.put("timeStamp", System.currentTimeMillis() / 1000 + "");//加时间戳参数
//        params.put("sign", MD5Util.md5(params));//md5加密并加参数
//
//        RetrofitManager.getDefault().create(ApiServer.class).getEpcGoodsListUrl(RetrofitManager.getHeader(),params)
//                .retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
//                    @Override
//                    public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
//                        // 参数Observable<Throwable>中的泛型 = 上游操作符抛出的异常，可通过该条件来判断异常的类型
//                        return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
//                            @Override
//                            public ObservableSource<?> apply(Throwable throwable) throws Exception {
//                                // 输出异常信息
//                                Trace.e("UpdateService，wcj:Goods+++++：" + throwable.toString());
//                                /**
//                                 * 需求1：根据异常类型选择是否重试
//                                 * 即，当发生的异常 = 网络异常 = IO异常 才选择重试
//                                 */
////                                if (throwable instanceof IOException) {
////                                    Trace.e("UpdateService，wcj+++++：" + "属于IO异常，需重试");
//                                /**
//                                 * 需求2：限制重试次数
//                                 * 即，当已重试次数 < 设置的重试次数，才选择重试
//                                 */
//                                if (currentRetryGoodsCount < maxConnectCount) {
//                                    // 记录重试次数
//                                    currentRetryGoodsCount++;
//                                    Trace.e("UpdateService，wcj:Goods+++++：重复次数" + +currentRetryGoodsCount);
//                                    /**
//                                     *  需求2：实现重试
//                                     *  通过返回的Observable发送的事件 = Next事件，从而使得retryWhen（）重订阅，最终实现重试功能
//                                     *  * *
//                                     *  需求3：延迟1段时间再重试
//                                     *  * 采用delay操作符 = 延迟一段时间发送，以实现重试间隔设置
//                                     *  *
//                                     *  * 需求4：遇到的异常越多，时间越长 *
//                                     *  在delay操作符的等待时间内设置 = 每重试1次，增多延迟重试时间1s *
//                                     */
//                                    // 设置等待时间
//                                    waitRetryGoodsTime = 1000 + waitRetryGoodsTime * 1000;
//                                    Trace.e("UpdateService，wcj:Goods+++++： 等待时间 =" + waitRetryGoodsTime);
//                                    return Observable.just(1).delay(waitRetryGoodsTime, TimeUnit.MILLISECONDS);
//                                } else {
//                                    // 若重试次数已 > 设置重试次数，则不重试
//                                    // 通过发送error来停止重试（可在观察者的onError（）中获取信息）
//                                    return Observable.error(new Throwable("重试次数已超过设置次数 = " + currentRetryGoodsCount + "，即 不再重试"));
//                                }
////                                }
//                                // 若发生的异常不属于I/O异常，则不重试
//                                // 通过返回的Observable发送的事件 = Error事件 实现（可在观察者的onError（）中获取信息）
////                                else {
////                                    return Observable.error(new Throwable("发生了非网络异常（非I/O异常）"));
////                                }
//                            }
//                        });
//                    }
//                })
//                .subscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe(new Observer<BaseListResult<EpcGoodsInfo>>() {
//                    @Override
//                    public void onSubscribe(Disposable d) {
//
//                    }
//
//                    @Override
//                    public void onNext(BaseListResult<EpcGoodsInfo> result) {
//                        if (result.isSuccess()) {
//                            List<EpcGoodsInfo> list = result.getData();
//                            if (null != list && list.size() > 0) {
//                                EpcGoodsInfoDao epcGoodsInfoDao = GreenDaoUtils.getSingleTon().getmDaoSession().getEpcGoodsInfoDao();
//                                for (EpcGoodsInfo info : list) {
//                                    epcGoodsInfoDao.insertOrReplace(info);
//                                }
//                                PreferenceUtil.getInstance().commitBoolean(PreferenceUtil.LABEL_IS_LOADED, true);//本地记录加载成功
//                                if (list.size() == 10000){
//                                    goodsPageIndex ++;
//                                    getGoodsLabel();
//                                    Trace.e("UpdateService:wcj:Goods+++++++++++++++"+ goodsPageIndex);
//                                }
//                            } else {
//                                Trace.e("UpdateService，wcj:Goods+++++：" + "数据为空");
//                            }
//                        } else {
//                            Trace.e("UpdateService，wcj:Goods+++++：" + result.getType());
//                        }
//                    }
//
//                    @Override
//                    public void onError(Throwable e) {
//                        Trace.e("UpdateService，wcj:Goods+++++：" + e.getMessage());
//                    }
//
//                    @Override
//                    public void onComplete() {
//
//                    }
//                });
//
//
//    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mTimer != null) {
            mTimer.cancel();
            mTimer = null;
        }
        if (timerTask != null) {
            timerTask.cancel();
            timerTask = null;
        }
    }
}
